//#include <pic.h>
#include "tenx_TM56F1522.h"
#include "Sys_Bsp.h"
#include "gpio.h"
#include "Timerx.h"
#include "adc.h"
#include "ISR.h"
#include "led.h"
#include "INTx.h"
#include "EEPROM.h"
#include "wktwdt.h"
//#include "uart.h"


const unsigned int szTemp @0x0FFE=0;//Don't remove or remark this line.

#define Rload_1ms  5
#define VREF 496   //2480
#define VMIN 3000
#define VMAX 4200

unsigned int ADC_VAL = 0;
unsigned char Smoke_Cnt=0;
unsigned int Smoke_time = 0;
unsigned int Shk_smoke = 0;
unsigned int Cnt_2s_smoke = 0;
unsigned int event;
//unsigned int Bat_Volt;
unsigned int Bat_percent;
unsigned int voltage;
unsigned int voltage_one;
unsigned int voltage_point;
unsigned int voltage_point2;
unsigned int time_cout;
unsigned int Charge_gap;

unsigned int ten;
unsigned int one;
extern unsigned int mark_state;

void charge_scan();
void smoke_stop_scan();
void liquid_scan();
void Adc_Value_to_Voltage();

//--------------------------------------
//main function
void main(void)
{
    /*-------------------------------------------------
    Write 37h to force LVR+POR Disable
    Write 38h to force LVR Disable, POR still enable
    Write 39h to force POR Disable, LVR still enable
    Write others LVR and POR enable
    -------------------------------------------------*/
    LVRPD  =0; 
      
    LVRSAV =1; // POR/LVR auto power off in STOP/IDLE mode
    LVDSAV =1; // LVD auto power off in STOP/IDLE mode
    //PDCMP  =0; // Disable Comparator & DAC power down ee部分

    Bsp_SysClock_Config(SCK_SRC,FCK_FRC,SysClk_FCK,SysClkPsc_Div1);
    LED_Init();         //IO引脚初始化

    Timer0_Init(TM0_FsysDiv2,TM01_ClkPsc_32,Rload_1ms);   //16/2/32 
    Wdt_Init(WKTWdtPsc_Div4);

    Adc_Init(AdcClk_Div32,AdcVref_2P48V,AdcChanel_PA2);    //ADC频率小于1M
    INTx_Init(ExINT0,INTxPin_PA,INTxEDG_Rising);        //PA3上升沿触发
    Interrupt_EnConfig(IntSrc_TMR0|IntSrc_INT0);

    TM0Cnt_En(Enable);

    Smoke_Cnt = EEPROM_ReadByte(0);
    
    mark_state = full_liquid;

    while(1)
    {
       if(event & EVENT_TIME0)   //1ms执行一次
       {
          event_clr(EVENT_TIME0);
         //HW_Led_Scan(5,5);
          HW_Led_Scan(ten,one);
       }
       
       if(event & EVENT_20ms)   //20ms执行一次
       {
          event_clr(EVENT_20ms);
          charge_scan();       //充电检测
          liquid_scan();
          if(event & EVENT_CHARGE)
          {
              mark_state |= 0x01;     //充电显示
              time_cout = 0;
          }
          else
          {
              //电池电压4200mv为满电，低于3000mv时为低电，mcu不工作
              mark_state &= 0xFE;     //充电不亮
          }

          if(event & EVENT_Smoke)
          {
               time_cout = 0;
               smoke_stop_scan();     //检测抽烟结束，并增加次数
          }else
          {
               Cnt_2s_smoke = 0;     //抽烟时长达到两秒才算
               if(event & EVENT_2s)   //延长电量显示刷新时间，避免led闪烁
               {
                  event_clr(EVENT_2s);
                  Adc_Value_to_Voltage(); 
               }
          }

          if(!((event & EVENT_CHARGE) || (event & EVENT_Smoke)))   //进入停止模式
         {
            if(++ time_cout >= 500)  //10s后进入睡眠
            {
               time_cout = 0;
               PxMOD_Config(GPIO_PA,0xF0,GPIOx_CmosOutL);        // 进入睡眠前关闭LED  
               PxMOD_Config(GPIO_PB,0xFF,GPIOx_CmosOutL);        // 
               PxMOD_Config(GPIO_PA,Bit_1|Bit_0,GPIOx_InputPU);  // PA[1:0] 输入上拉
               PxMOD_Config(GPIO_PD,0x02,GPIOx_InputPD_WKUP);
               SLOWSTP=1;   //0:空闲模式   1:停止模式
               asm("sleep");
               asm("nop");
               asm("nop");
               asm("CLRWDT"); // clear wdt 
            }
         }
       }
       
    }
}


unsigned int Cnt_20ms = 0;
unsigned int Cnt_1s = 0;
unsigned int Cnt_2s = 0;

//--------------------------------------
void interrupt Int_ISR(void)  
{
	if(TM0IF==1)
	{	
	   TM0IF=0;
      event_set(EVENT_TIME0);
      if(++ Cnt_20ms >= 20)
      {
         Cnt_20ms = 0;
         event_set(EVENT_20ms);
         if(++ Cnt_2s >= 100)
         {
            Cnt_2s = 0;
            event_set(EVENT_2s);
         }
         
      }
   }

   if(INT0IF==1)   //外部中断 检测到抽烟
	{	
      event_set(EVENT_Smoke);
	   INT0IF=0;
      Shk_smoke = 0;
   }
   else
   {
      if(event & EVENT_Smoke)
      {
         if(PA3 == 0)
         {
             if(++ Shk_smoke > 400)    //结束400ms 
            {
               Shk_smoke = 0;
               Cnt_2s_smoke = 0;    //延长2s计数
               event_clr(EVENT_Smoke);
               event_clr(EVENT_shk_smoke);
            }
         }
          
      }
   }
   
}
 
//充电扫描
void charge_scan()
{
     if(PD1 == 1)
     {
        if(++ Cnt_1s > 50)
        {
           Cnt_1s = 0;
           event_set(EVENT_CHARGE);
        }
     }
     else
     {
         if(Cnt_1s > 0)
         {
            Cnt_1s --;  
         }
         if(Cnt_1s == 0)
         {
            event_clr(EVENT_CHARGE);
         }
         
     }
}

//抽烟检测
void smoke_stop_scan()
{
    if(++ Cnt_2s_smoke >= 100)
    {
       Cnt_2s_smoke = 0;
       event_set(EVENT_shk_smoke);
    }
    
    if(event & EVENT_shk_smoke)
    {
      Cnt_2s_smoke = 0;
      if(PA3 == 0)
      {
         if(++ Smoke_time > 20)    //结束400ms 计数一次
         {
            Smoke_time = 0;
            Smoke_Cnt ++;
            EEPROM_WriteByte(Smoke_Cnt,0);   //抽烟结束，写入ee
            event_clr(EVENT_Smoke);
            event_clr(EVENT_shk_smoke);
         }
      }
   }   
   
}

//油烟显示
void liquid_scan()
{
    if(Smoke_Cnt <= 3)
   {
      mark_state = full_liquid | 0x20;    //烟油状态全亮3格
   }else if(Smoke_Cnt <= 6)
   {
      mark_state = middle_liquid;    //烟油状态2格
   }else if(Smoke_Cnt <= 9)
   {
      mark_state = few_liquid;    //烟油状态1格
   }else
   {
      mark_state = 0x02;
   }
   if(Smoke_Cnt >10)   //循环测试用
   {
      Smoke_Cnt = 0;
   }
}

//使用整除时，数码管数值显示差距跳动大，如91直接到99，先将整除化为乘法再扩大倍数，可提高精度
void Adc_Value_to_Voltage()
{
    ADC_VAL = Adc_Get_Average();
    voltage = (unsigned long)ADC_VAL * 12;    //缩小倍数，误差减小2480/4095~= 605  605*2=1210  再缩小100倍减小整除误差
    //Bat_percent = ((voltage*2 -VMIN) * 100) / (VMAX - VMIN);   //电量百分比
    //Bat_percent = (Bat_percent + 5)/10;   //四舍五入到最接近的百分比
    voltage_one = (unsigned long)voltage / 10000;          //直接显示电压
    voltage_point = (unsigned long)voltage % 10000 / 1000 + 1;   //小数点后一位  误差偏小0.1v
    voltage_point2 = (unsigned long)voltage % 10000 % 1000 /100;  //小数点后两位
    if(event & EVENT_CHARGE)
    {
         if(voltage_one < 4)
        {
             Bat_percent = (unsigned long)((voltage_one * 100 + voltage_point * 10 + voltage_point2 - 10) - 334) * 116;
        }
        else 
        {
            if(((voltage_point * 10 + voltage_point2) < 3))
            {
                Bat_percent = (unsigned long)((voltage_one * 100 + voltage_point * 10 + voltage_point2 - 10) - 334) * 116;
            }
            else if((voltage_point * 10 + voltage_point2) < 5)
            {
                Bat_percent = (unsigned long)((voltage_one * 100 + voltage_point * 10 + voltage_point2 - 8) - 334) * 116;
            }
            else if((voltage_point * 10 + voltage_point2) < 10)
            {
                Bat_percent = (unsigned long)((voltage_one * 100 + voltage_point * 10 + voltage_point2 - 6) - 334) * 116;
            }
            else if((voltage_point * 10 + voltage_point2) < 15)
            {
                Bat_percent = (unsigned long)((voltage_one * 100 + voltage_point * 10 + voltage_point2 - 4) - 334) * 116;
            }
            else if((voltage_point * 10 + voltage_point2) < 18)
            {
                Bat_percent = (unsigned long)((voltage_one * 100 + voltage_point * 10 + voltage_point2 - 2) - 334) * 116;
            }
            else
            {
                Bat_percent = (unsigned long)((voltage_one * 100 + voltage_point * 10 + voltage_point2 - 1) - 334) * 116;
            }
            
        }
        Charge_gap = 1;    //用于减小充电时，电压检测带来的误差
    }
    else
    {
        Bat_percent = (unsigned long)((voltage_one * 100 + voltage_point * 10 + voltage_point2) - 334) * 116;   //100)/12;   //减去最小电压 100/86 =1.16
        Charge_gap = 0;
    }
    
   if((voltage_one <= 3)&&(((voltage_point - Charge_gap) * 10 + voltage_point2) <= 34))
    {
        ten = 0;
        one = 0;
    }
    else if((voltage_one >= 4)&&(voltage_point >= 2))       //满电
    {
        ten = 9;
        one = 9;
    }else
    {
        ten = Bat_percent / 1000;
        one = Bat_percent % 1000/100;
    }
    
    
   // uart_dat = (unsigned char)voltage;   
   // Simulation_Uart_Send();
    //return Bat_percent;
    //return voltage;
}
